import fs from 'fs'
import path from 'path'
import { promisify } from 'util'
import { H3Event } from 'h3'
import { randomUUID } from 'crypto'

const mkdir = promisify(fs.mkdir)
const writeFile = promisify(fs.writeFile)
const readdir = promisify(fs.readdir)
const unlink = promisify(fs.unlink)
const stat = promisify(fs.stat)
const rename = promisify(fs.rename)

const UPLOAD_DIR = path.resolve(process.cwd(), 'uploads')
const CHUNK_DIR = path.resolve(UPLOAD_DIR, 'chunks')

// 确保上传目录存在
if (!fs.existsSync(UPLOAD_DIR)) {
  fs.mkdirSync(UPLOAD_DIR, { recursive: true })
}
if (!fs.existsSync(CHUNK_DIR)) {
  fs.mkdirSync(CHUNK_DIR, { recursive: true })
}

export default defineEventHandler(async (event: H3Event) => {
  const { req, res } = event.node

  if (req.method !== 'POST') {
    res.statusCode = 405
    return { error: 'Method not allowed' }
  }

  try {
    const contentType = req.headers['content-type'] || ''

    if (contentType.includes('multipart/form-data')) {
      // 处理分片上传
      return await handleChunkUpload(event)
    } else if (contentType.includes('application/json')) {
      // 处理合并请求
      const body = await readBody(event)
      if (body.action === 'merge') {
        return await mergeChunks(body)
      }
    }

    return { error: 'Invalid request' }
  } catch (error) {
    console.error('Upload error:', error)
    res.statusCode = 500
    return { error: 'Internal server error' }
  }
})

async function handleChunkUpload(event: H3Event) {
  const formData = await readMultipartFormData(event)
  if (!formData) {
    throw new Error('Invalid form data')
  }

  const fileData = formData.find(item => item.name === 'file')
  const hash = formData.find(item => item.name === 'hash')?.data.toString()
  const filename = formData.find(item => item.name === 'filename')?.data.toString()

  if (!fileData || !hash || !filename) {
    throw new Error('Missing required fields')
  }

  // 保存分片到临时目录
  const chunkPath = path.resolve(CHUNK_DIR, hash)
  await writeFile(chunkPath, fileData.data)

  return { success: true, hash }
}

async function mergeChunks(body: any) {
  const { fileHash, filename, chunkCount } = body

  // 验证所有分片是否已上传
  const chunkFiles = await readdir(CHUNK_DIR)
  const uploadedChunks = chunkFiles.filter(name => name.startsWith(fileHash))

  if (uploadedChunks.length !== Number(chunkCount)) {
    throw new Error('Not all chunks have been uploaded')
  }

  // 按分片索引排序
  uploadedChunks.sort((a, b) => {
    const aIndex = parseInt(a.split('-').pop() || '0')
    const bIndex = parseInt(b.split('-').pop() || '0')
    return aIndex - bIndex
  })

  // 创建最终文件
  const filePath = path.resolve(UPLOAD_DIR, filename)
  const writeStream = fs.createWriteStream(filePath)

  // 合并所有分片
  for (const chunkName of uploadedChunks) {
    const chunkPath = path.resolve(CHUNK_DIR, chunkName)
    const chunkData = await fs.promises.readFile(chunkPath)
    writeStream.write(chunkData)
    await unlink(chunkPath) // 删除已合并的分片
  }

  writeStream.end()

  return new Promise((resolve, reject) => {
    writeStream.on('finish', () => {
      resolve({ success: true, path: filePath })
    })
    writeStream.on('error', (error) => {
      reject(error)
    })
  })
}